/*
 *****************************************************************************
 * Copyright by ams AG                                                       *
 * All rights are reserved.                                                  *
 *                                                                           *
 * IMPORTANT - PLEASE READ CAREFULLY BEFORE COPYING, INSTALLING OR USING     *
 * THE SOFTWARE.                                                             *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         *
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS         *
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  *
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,     *
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT          *
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     *
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     *
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       *
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE     *
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.      *
 *****************************************************************************
 */
/*
 *      PROJECT:   AS3911 firmware
 *      $Revision: $
 *      LANGUAGE:  ANSI C
 */

/*! \file
 *
 *  \author Christian Eisendle
 *
 *  \brief Implementation of ISO-14443B
 *
 */

#ifndef ISO_14443_B_H
#define ISO_14443_B_H

/*
******************************************************************************
* INCLUDES
******************************************************************************
*/
#include "platform.h"

/*
******************************************************************************
* GLOBAL DEFINES
******************************************************************************
*/
#define ISO14443B_PUPI_LENGTH 4
#define ISO14443B_APPDATA_LENGTH 4
#define ISO14443B_PROTINFO_LENGTH 3
/*
******************************************************************************
* GLOBAL DATATYPES
******************************************************************************
*/
/*! 
 * PCD command set.
 */
typedef enum
{
    ISO14443B_CMD_REQB = 0x00,  /*!< command REQB */
    ISO14443B_CMD_WUPB = 0x08, /*!< command WUPB */
    ISO14443B_CMD_HLTB = 0x50, /*!< command HLTB */
    ISO14443B_CMD_ATTRIB = 0x1D, /*!< command ATTRIB */
}iso14443BCommand_t;

/*! 
 * slot count (N parameter) used for iso14443b anti collision
 */
typedef enum
{
    ISO14443B_SLOT_COUNT_1 = 0,
    ISO14443B_SLOT_COUNT_2 = 1,
    ISO14443B_SLOT_COUNT_4 = 2,
    ISO14443B_SLOT_COUNT_8 = 3,
    ISO14443B_SLOT_COUNT_16 = 4,
}iso14443BSlotCount_t;

/*!  
 * struct representing the content of ATQB
 * See ISO14443b spec. for more information.
 */
typedef struct
{
    u8 atqb; /*<! content of answer to request byte */
    u8 pupi[ISO14443B_PUPI_LENGTH]; /*!< UID of the PICC */
    u8 applicationData[ISO14443B_APPDATA_LENGTH]; /*!< application specific data */
    u8 protocolInfo[ISO14443B_PROTINFO_LENGTH]; /*!< protocol info */
    bool collision; /*!< TRUE, if there was a collision which has been resolved,
                        otherwise no collision occured */
}iso14443BProximityCard_t;

/*! 
 * struct holding parameter needed for ATTRIB command
 * The parameters are called param1, param2, param3 and
 * param4 and are described in ISO14443-3 spec.
 */
typedef struct
{
    u8 param1;
    u8 param2;
    u8 param3;
    u8 param4;
}iso14443BAttribParameter_t;

/*! 
 * struct holding the answer to ATTRIB command
 */
typedef struct
{
    u8 mbli; /*!< maximum buffer length */
    u8 cid;  /*!< logical card identifier */
}iso14443BAttribAnswer_t;

/*
******************************************************************************
* GLOBAL FUNCTION PROTOTYPES
******************************************************************************
*/
/*! 
 *****************************************************************************
 *  \brief  Initialize ISO14443-B mode.
 *  \note This function needs to be called every time after switching
 *  from a different mode to initialize ISO14443-B configuration.
 *  During initialization a calibration of the modulation depth is started
 *  using #as3911CalibrateModulationDepth which result is stored to \a result.
 *
 *  \param[in] mi : Desired modulation index value, e.g. AS3911_REG_AM_MOD_DEPTH_CONTROL_mod_10percent
 *  \param[out] result : Result of calibration of modulation depth
 *
 *  \return ERR_IO : Error during communication.
 *  \return ERR_NONE : No error.
 *
 *****************************************************************************
 */
extern s8 iso14443BInitialize(u8 mi, u8* result);

/*! 
 *****************************************************************************
 *  \brief  Deinitialize ISO14443-B mode.
 *  \note This function should be called every time iso 14443b is not needed
 *  any more.
 *  \param keep_on: if true the RF field will not be switched off
 *  \return ERR_NONE : No error.
 *
 *****************************************************************************
 */
extern s8 iso14443BDeinitialize(u8 keep_on);

/*! 
 *****************************************************************************
 *  \brief  Select a PICC and put it into READY_DECLARED state
 *
 *  This function sends to all PICCs in field either the REQB or the
 *  WUPB (depending on \a cmd parameter). Depending on \a slotCount
 *  one or more PICC with matched \a afi send back their PUPI and
 *  change their state to READY_DECLARED. All other PICCs change to READY_REQUESTED.
 *  If more PICCs send their PUPI a collision occurs and the anti-collision
 *  algorithm is started until only one PICC is in READY_DECLARED state.
 *  The PUPI of this PICC is then stored in \a card.
 *
 *  \param[in] cmd : Used command to put the PICCs in READY state. This
 *                   could either be #ISO14443B_CMD_REQB or #ISO14443B_CMD_WUPB
 *  \param[out] card : Parameter of type #iso14443BProximityCard_t which holds
 *                the found card then.
 *  \param[in] afi : application family identifier (Refer to ISO14443-3)
 *  \param[in] slotCount : Parameter used for REQB/WUPB. Refer to ISO14443-3
 *                         for more information.
 *
 *  \return ERR_TIMEOUT : Timeout waiting for interrupts or no reply from cards.
 *  \return ERR_NOTFOUND : No PICC could be selected..
 *  \return ERR_IO : Error during communication.
 *  \return ERR_NONE : No error.
 *
 *****************************************************************************
 */
extern s8 iso14443BSelect(iso14443BCommand_t cmd,
                        iso14443BProximityCard_t* card,
                        u8 afi,
                        iso14443BSlotCount_t slotCount);

/*! 
 *****************************************************************************
 *  \brief  Send the HLTB command
 *
 *  This function is used to send the HLTB command to put one or more PICCs to
 *  state HALT so that they do not reply to further REQB commands (only to WUPB).
 *  \note PICC must be in state READY_DECLARED state using #iso14443BSelect
 *
 *  \param[in] card : Card to which the HLTB command shall be sent to
 *  \return ERR_NOMSG : PICC send not acknowledge
 *  \return ERR_TIMEOUT : Timeout waiting for interrupts.
 *  \return ERR_IO : Error during communication.
 *  \return ERR_NONE : No error.
 *
 *****************************************************************************
 */
extern s8 iso14443BSendHltb(iso14443BProximityCard_t* card);

/*! 
 *****************************************************************************
 *  \brief  Enter protocol mode
 *
 *  This function is used to send the ATTRIB command which puts the PICC
 *  into protocol mode. The PICC must be in READY_DECLARED state using #iso14443BSelect
 *  command.
 *
 *  \param[in] card : parameter of type #iso14443BProximityCard_t representing
 *          the PICC to be put into protocol state. (\a pupi member)
 *  \param[in] param : parameter sent with attrib command (see ISO14443-3 spec)
 *  \param[out] answer : answer to attrib command
 *
 *  \return ERR_NOTFOUND : PICC not in field or in right state.
 *  \return ERR_TIMEOUT : Timeout during transmit.
 *  \return ERR_IO : Error during communication.
 *  \return ERR_NONE : No error, answer received and written to \a answer, PICC
 *                     now in protocol state.
 *
 *****************************************************************************
 */
extern s8 iso14443BEnterProtocolMode(iso14443BProximityCard_t* card,
                                iso14443BAttribParameter_t* param,
                                iso14443BAttribAnswer_t* answer);

extern s8 guid_B(u8 *atqb, u16 *len);
extern s8 selectb(u8 *atqb, u16 *len);
/*! 
 *****************************************************************************
 *  \brief  Deselect a PICC
 *
 *  This function deselects a PICC which is in PROTOCOL state. The card
 *  is identified using \a cid.
 *
 *  \param[in] cid : logical number of the addressed PICC (see ISO14443-4)
 *
 *  \return ERR_NOTFOUND : PICC not in field or in right state.
 *  \return ERR_IO : Error during communication.
 *  \return ERR_NONE : No error.
 *
 *****************************************************************************
 */
extern s8 iso14443BDeselect(u8 cid);

#endif /* ISO_14443_B_H */

